package server;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;

import scheduler.ILinkRepository;
import scheduler.IScheduler;
import structures.InfoPacket;

class ConnectionWriterThread implements Runnable 
{
	private Socket sock;
	//private ILinkRepository linkRep;
	private IScheduler scheduler;
	private ObjectOutputStream out;
	//private ObjectInputStream in;

	ConnectionWriterThread(Socket sock, ILinkRepository linkRep, IScheduler scheduler)
	{
		this.sock = sock;
		//this.linkRep = linkRep;
		this.scheduler = scheduler;
	}
	
	public void run()
	{
		try {
			//in = new ObjectInputStream(sock.getInputStream());
			out = new ObjectOutputStream(sock.getOutputStream());
			//InfoPacket pck = null;
			String URL;
			while((URL = scheduler.getTask())!=null)
			{
				out.writeObject(new InfoPacket(URL, "wawro"));		//napisane pod testy, poporawić!
			}
			/*
			out.writeObject(new InfoPacket(scheduler.getTask()));	//Connection 
			
			while((pck = (InfoPacket)in.readObject())!=null)
			{
				linkRep.saveLinks(pck.getUrlList());
				out.writeObject(new InfoPacket(scheduler.getTask()));
			}
			
			*/
		} catch (IOException e) 
		{
			e.printStackTrace();
		}		
	}
}

class ConnectionReaderThread implements Runnable 
{
	private Socket sock;
	private ILinkRepository linkRep;
	//private IScheduler scheduler;
	//private ObjectOutputStream out;
	private ObjectInputStream in;

	ConnectionReaderThread(Socket sock, ILinkRepository linkRep, IScheduler scheduler)
	{
		this.sock = sock;
		this.linkRep = linkRep;
		//this.scheduler = scheduler;
	}
	
	public void run()
	{
		try {
			in = new ObjectInputStream(sock.getInputStream());
			//out = new ObjectOutputStream(sock.getOutputStream());
			InfoPacket pck = null;

			while((pck = (InfoPacket)in.readObject())!=null)
			{
				System.out.println("CrawlerServer (ReaderThread) : odebrałem listę linków: " + pck.getUrlList());
				linkRep.saveLinks(pck.getUrlList());
			}
		} catch (IOException e) 
		{
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}		
	}
}


public class CrawlerServer implements Runnable {
	private ServerSocket srvSock;
	private ILinkRepository linkRep;
	private IScheduler scheduler;
	
	public CrawlerServer(int port, IScheduler scheduler, ILinkRepository linkRep) 
	{
		this.linkRep = linkRep;
		this.scheduler = scheduler;
		try {
			srvSock = new ServerSocket(port);
		} catch (IOException e) {
			e.printStackTrace();
		}

	}
	/*
	public void turnOn()
	{
		new Thread(this).start();
	}
	*/
	//public void kill
	
	public void run() {
		System.out.println("CrawlerServer rozpoczyna działanie");
		Socket s;
		Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
			
			@Override
			public void run() {
				try {
					srvSock.close();
				} catch (IOException e) {
					e.printStackTrace();
				}

			}
		}));
		
		try {
			
			while ((s = srvSock.accept()) != null) {
				System.out.println("CrawlerServer zaakceptował połączenie");
				new Thread(new ConnectionWriterThread(s, linkRep, scheduler)).start();
				new Thread(new ConnectionReaderThread(s, linkRep, scheduler)).start();
			}
		} catch (IOException e) {
		}
	}
}
